<?php
class DateHelper {
	/**
	 * To add minutes with the given timestamp date value
	 * To use substract use negative sign with the minute value
	 * Method will return equialant timestamp value after calculation
	 */
	public static function addMinutesToDate($timeStamp, $totalMinutes)
	{
		// You can add as many days as you want. mktime will accumulate to the next month / year.
		$thePHPDate = getdate($timeStamp);
			
		$thePHPDate['minutes'] = $thePHPDate['minutes']+$totalMinutes;
		$timeStamp = mktime($thePHPDate['hours'], $thePHPDate['minutes'], $thePHPDate['seconds'], $thePHPDate['mon'], $thePHPDate['mday'], $thePHPDate['year']);
		return $timeStamp;
	}

	/**
	 * To add hours with the given timestamp date value
	 * To use substract use negative sign with the hour value
	 * Method will return equialant timestamp value after calculation
	 */
	public static function addHoursToDate($timeStamp, $totalHours)
	{
		// You can add as many days as you want. mktime will accumulate to the next month / year.
		$thePHPDate = getdate($timeStamp);
			
		$thePHPDate['hours'] = $thePHPDate['hours']+$totalHours;
		$timeStamp = mktime($thePHPDate['hours'], $thePHPDate['minutes'], $thePHPDate['seconds'], $thePHPDate['mon'], $thePHPDate['mday'], $thePHPDate['year']);
		return $timeStamp;
	}


	/**
	 * To add hours with the given timestamp date value
	 * To use substract use negative sign with the hour value
	 * Method will return equialant timestamp value after calculation
	 */
	public static function addDaysToDate($timeStamp, $totalDays)
	{
		// You can add as many days as you want. mktime will accumulate to the next month / year.
		$thePHPDate = getdate($timeStamp);
			
		$thePHPDate['mday'] = $thePHPDate['mday']+$totalDays;
		$timeStamp = mktime($thePHPDate['hours'], $thePHPDate['minutes'], $thePHPDate['seconds'], $thePHPDate['mon'], $thePHPDate['mday'], $thePHPDate['year']);
		return $timeStamp;
	}

	/**
	 * Calculate remaining time from the given datetime and the future datetime in timstamp
	 * Method will return an array of time remaining years, months, days, hours, minutes, and seconds
	 */
	public static function calculateTimeRemaining($fromTimeStamp, $toTimestamp)
	{
		$year_until		= (int)(($toTimestamp - $fromTimeStamp)/31536000);
		$days_until		= (int)(($toTimestamp - $fromTimeStamp)/86400);
		$hours_until	= (int)(($toTimestamp - $fromTimeStamp)/3600);
		$minutes_until	= (int)(($toTimestamp - $fromTimeStamp)/60);
		$seconds_until	= (int)(($toTimestamp - $fromTimeStamp)/1);

		$hour_offset	= $hours_until;
		$minute_offset	= $minutes_until;
			
		$hours_until	-= $days_until * 24;
		$minutes_until	-= $hour_offset * 60;
		$seconds_until	-= $minute_offset * 60;

		$before_since	= (int)(($toTimestamp - $fromTimeStamp)/1);
		$factor			= ($before_since < 0)	? -1 : 1;
			
		//Keep negative values if time remaining exceeds the target datetime
		$arrDateRemaining['years']		= $year_until;
		$arrDateRemaining['days']		= $days_until;
		$arrDateRemaining['hours']		= $hours_until;
		$arrDateRemaining['minutes']	= $minutes_until;
		$arrDateRemaining['seconds']	= $seconds_until;

		$arrDateRemaining['is_passed']	= ($factor != -1) ? 0 : 1;

		return $arrDateRemaining;
	}

	/**
	 * Format time remaining data as language specific
	 */
	public static function formatTimeRemainingString($arrTimeRemaining, &$isTimeOut, $language='auto')
	{
		if($language == 'auto'){
			$language = 'zh';
		}

		if(!$arrTimeRemaining['is_passed']){

			switch($language){
				case 'en':
					$strTimeRemaining = ($arrTimeRemaining['years'] ? $arrTimeRemaining['years'] : '')
					. ($arrTimeRemaining['days'] ? $arrTimeRemaining['days'].' days ' : '')
					. ($arrTimeRemaining['hours'] ? $arrTimeRemaining['hours'].' hours ' : '')
					. ($arrTimeRemaining['minutes'] ? $arrTimeRemaining['minutes'].' minutes ' : '');
					//. ($arrTimeRemaining['seconds'] ? $arrTimeRemaining['seconds'].' seconds ' : '');
					break;
				case 'zh':
					$strTimeRemaining = ($arrTimeRemaining['years'] ? $arrTimeRemaining['years'] : '')
					. ($arrTimeRemaining['days'] ? $arrTimeRemaining['days'].'天' : '')
					. ($arrTimeRemaining['hours'] ? $arrTimeRemaining['hours'].'小时' : '')
					. ($arrTimeRemaining['minutes'] ? $arrTimeRemaining['minutes'].'分' : '');		
					break;
			}
		}else{
			$isTimeOut = true;

			$strTimeRemaining = ''; //over
		}

		return $strTimeRemaining;
	}


	/**
	 * To subtract the days from the date
	 * Method will return a date after calculation
	 */
	public static function subtractDaysFromDate($date, $totalDays)
	{
		if(strstr($date,"-"))
		list($y,$m,$d) = split("-",$date);

		if(strstr($date,"/"))
		list($y,$m,$d) = split("/",$date);

		return date('Y-m-d', mktime(0, 0, 0, $m , $d-$totalDays, $y));
	}

	/**
	 * To Add the days to the date
	 * Method will return a date after calculation
	 */
	public static function AddDayToDate($date, $totalDays)
	{
			
		if(strstr($date,"-"))
		list($y,$m,$d) = split("-",$date);

		if(strstr($date,"/"))
		list($y,$m,$d) = split("/",$date);

		return date('Y-m-d', mktime(0, 0, 0, $m , $d+$totalDays, $y));
	}

	/**
	 * To Get current time
	 * Method will return a ini value
	 */

	public static function getCurrentTime($userTZ){
		$default_timezone = date_default_timezone_get();
		$timeZoneAddition = 0;
		if ($default_timezone == "UTC") $timeZoneAddition = $userTZ;
		return time() + $timeZoneAddition * 3600;
	}

	/**
	 * Converts a date string to a timestamp.
	 * @param string the date string to be parsed
	 * @param string the pattern that the date string is following
	 * @return integer timestamp for the date string. False if parsing fails.
	 */
	public static function parse($value,$pattern='MM/dd/yyyy')
	{
		$tokens=self::tokenize($pattern);
		$i=0;
		$n=strlen($value);
		foreach($tokens as $token)
		{
			switch($token)
			{
				case 'yyyy':
					{
						if(($year=self::parseInteger($value,$i,4,4))===false)
						return false;
						$i+=4;
						break;
					}
				case 'yy':
					{
						if(($year=self::parseInteger($value,$i,1,2))===false)
						return false;
						$i+=strlen($year);
						break;
					}
				case 'MM':
					{
						if(($month=self::parseInteger($value,$i,2,2))===false)
						return false;
						$i+=2;
						break;
					}
				case 'M':
					{
						if(($month=self::parseInteger($value,$i,1,2))===false)
						return false;
						$i+=strlen($month);
						break;
					}
				case 'dd':
					{
						if(($day=self::parseInteger($value,$i,2,2))===false)
						return false;
						$i+=2;
						break;
					}
				case 'd':
					{
						if(($day=self::parseInteger($value,$i,1,2))===false)
						return false;
						$i+=strlen($day);
						break;
					}
				case 'h':
				case 'H':
					{
						if(($hour=self::parseInteger($value,$i,1,2))===false)
						return false;
						$i+=strlen($hour);
						break;
					}
				case 'hh':
				case 'HH':
					{
						if(($hour=self::parseInteger($value,$i,2,2))===false)
						return false;
						$i+=2;
						break;
					}
				case 'm':
					{
						if(($minute=self::parseInteger($value,$i,1,2))===false)
						return false;
						$i+=strlen($minute);
						break;
					}
				case 'mm':
					{
						if(($minute=self::parseInteger($value,$i,2,2))===false)
						return false;
						$i+=2;
						break;
					}
				case 's':
					{
						if(($second=self::parseInteger($value,$i,1,2))===false)
						return false;
						$i+=strlen($second);
						break;
					}
				case 'ss':
					{
						if(($second=self::parseInteger($value,$i,2,2))===false)
						return false;
						$i+=2;
						break;
					}
				default:
					{
						$tn=strlen($token);
						if($i>=$n || substr($value,$i,$tn)!==$token)
						return false;
						$i+=$tn;
						break;
					}
			}
		}
		if($i<$n)
		return false;

		if(!isset($year))
		$year=date('Y');
		if(!isset($month))
		$month=date('n');
		if(!isset($day))
		$day=date('j');

		if(strlen($year)===2)
		{
			if($year>70)
			$year+=1900;
			else
			$year+=2000;
		}
		$year=(int)$year;
		$month=(int)$month;
		$day=(int)$day;

		if(!isset($hour) && !isset($minute) && !isset($second))
		$hour=$minute=$second=0;
		else
		{
			if(!isset($hour))
			$hour=date('H');
			if(!isset($minute))
			$minute=date('i');
			if(!isset($second))
			$second=date('s');
			$hour=(int)$hour;
			$minute=(int)$minute;
			$second=(int)$second;
		}

		if(CTimestamp::isValidDate($year,$month,$day) && CTimestamp::isValidTime($hour,$minute,$second))
		return CTimestamp::getTimestamp($hour,$minute,$second,$month,$day,$year);
		else
		return false;
	}

	private static function tokenize($pattern)
	{
		if(!($n=strlen($pattern)))
		return array();
		$tokens=array();
		for($c0=$pattern[0],$start=0,$i=1;$i<$n;++$i)
		{
			if(($c=$pattern[$i])!==$c0)
			{
				$tokens[]=substr($pattern,$start,$i-$start);
				$c0=$c;
				$start=$i;
			}
		}
		$tokens[]=substr($pattern,$start,$n-$start);
		return $tokens;
	}

	protected static function parseInteger($value,$offset,$minLength,$maxLength)
	{
		for($len=$maxLength;$len>=$minLength;--$len)
		{
			$v=substr($value,$offset,$len);
			if(ctype_digit($v))
			return $v;
		}
		return false;
	}
}
?>